package com.gx.security.asymmetric;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.crypto.util.PrivateKeyFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * Created by gx on 2017/3/29.
 */
public class RSATest {
    private static String src = "imooc security RSA";
    private static String password = "gaoxing";
    private static final String PUBLIC_KEY = "SenderDHPublicKey";
    private static final String PRIVATE_KEY = "SenderDHPrivateKey";
    private static final int KEY_SIZE = 1024;

    public static final String ALGORITHM = "DH";


    public static void main(String[] args) {
        jdkRSA();
    }

    public static void jdkRSA(){
        try {
            //初始化秘钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");

            //初始化长度
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            System.out.println("Public Key:" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            System.out.println("PrivateKey :" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
            //私钥加密 公钥解密 -- -- 这种方式加密处理
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            //指定加密方式
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,privateKey);
            byte [] result  = cipher.doFinal(src.getBytes());
            System.out.println("RSA 私钥加密 公钥解密  加密结果: "+Base64.encodeBase64String(result));


            //私钥加密 公钥解密 -- -- 这种方式解密处理
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey  = keyFactory.generatePublic(x509EncodedKeySpec);
            //解密
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,publicKey);
            result = cipher.doFinal(result);
            System.out.println("RSA 私钥加密 公钥解密   解密结果 : "+new String(result));









            //公钥加密 私钥解密 -- -- 这种方式加密处理
            x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            publicKey  = keyFactory.generatePublic(x509EncodedKeySpec);
            //加密
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,publicKey);
            result = cipher.doFinal(src.getBytes());
            System.out.println("RSA 公钥加密 私钥解密   加密结果 : "+Base64.encodeBase64String(result));

            //解密
            pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            //指定加密方式
            keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,privateKey);
            result  = cipher.doFinal(result);
            System.out.println("RSA 公钥加密 私钥解密  加密结果: "+new String(result));
            //公钥加密 私钥解密 -- -- 这种方式解密处理




        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }


    }
}
